﻿#pragma once
#include <coroutine>
#include "log.h"
namespace as
{
	namespace co
	{
		template<class t_promise>
		struct Awaitable : public std::coroutine_handle<t_promise>
		{
			/*Awaitable():std::coroutine_handle<t_promise>() {
				LOG_DEBUG << "awaitable create:" << this;
			}*/
			~Awaitable() {
				LOG_DEBUG << "awaitable delete:" << this;
			}

			using promise_type = t_promise;
		};

		struct as_promise
		{
			as_promise() 
			{
				LOG_DEBUG << "as_promise create:" << this;
			}
			~as_promise()
			{
				LOG_DEBUG << "as_promise delete:" << this;
			}
			Awaitable<as_promise> get_return_object() 
			{ 
				std::coroutine_handle<as_promise> pro = Awaitable<as_promise>::from_promise(*this);
				Awaitable<as_promise> p{ pro };
				return p;
			}

			std::suspend_never initial_suspend() noexcept { return {}; }
			std::suspend_never final_suspend() noexcept { return {}; }
			void return_void() {}
			void unhandled_exception() {}
		};

		using coroutine_handle = std::coroutine_handle<as_promise>;

		//template<class return_type>
		//struct as_re_promise
		//{
		//	Awaitable<as_re_promise<return_type> > get_return_object() { return { Awaitable<as_re_promise<return_type> >::from_promise(*this) }; }
		//	std::suspend_never initial_suspend() noexcept { return {}; }
		//	std::suspend_never final_suspend() noexcept { return {}; }
		//	return_type return_value() { return val_; }
		//	void unhandled_exception() {}
		//	return_type val_;
		//};

		//template<class return_type>
		//using coroutine_re_handle = std::coroutine_handle <as_re_promise<return_type> >;
	}
}
